
package com.huawei.housekeeper.config.filter;

import com.huawei.housekeeper.common.enums.ErrorCode;
import com.huawei.housekeeper.commonutils.result.Result;
import com.huawei.housekeeper.commonutils.utils.JsonUtil;
import com.huawei.housekeeper.commonutils.utils.JwtTokenUtil;

import io.jsonwebtoken.ExpiredJwtException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 当未登录或者token失效访问接口时，自定义的返回结果
 */
@Component
@RefreshScope
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private final static Logger logger = LoggerFactory.getLogger(RestAuthenticationEntryPoint.class);

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException authException) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.setHeader("Access-Control-Expose-Headers", "Authorization, Metis-Role");
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE");
        response.setHeader("Access-Control-Allow-Origin", "*");
        Result<String> result = null;
        String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (StringUtils.isNotBlank(authHeader) && authHeader.startsWith(tokenHead)) {
            String token = authHeader.substring(tokenHead.length());
            try {
                if (jwtTokenUtil.isTokenExpired(token)) {
                    result = Result.createResult(ErrorCode.TOKEN_EXPIRED);
                }
            } catch (Exception e) {
                if (e instanceof ExpiredJwtException) {
                    logger.error("Token非法，token:{}", authHeader);
                    result = Result.createResult(ErrorCode.TOKEN_EXPIRED);
                }
            }
        } else {
            logger.error("Token非法，token:{}", authHeader);
            result = Result.createResult(ErrorCode.TOKEN_ERROR);
        }
        response.getWriter().println(JsonUtil.objectToJson(result));
        response.setStatus(401); // Aspect无法 处理 Adapter中错误 Adapter先执行
        response.getWriter().flush();
        response.flushBuffer();
    }
}
